package com.example.express.service;

import com.example.express.config.SfConfig;
import com.example.express.mapper.ExpressMapper;
import com.example.express.model.sf.exp.*;
import com.example.express.util.*;
import com.google.gson.Gson;
import com.sf.csim.express.service.HttpClientUtil;
import com.sf.csim.express.service.IServiceCodeStandard;
import com.sf.csim.express.service.code.ExpressServiceCodeEnum;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Service
public class SfExpServiceImpl implements SfExpService{

    @Resource
    private SfConfig sfConfig;

    @Resource
    private ExpressMapper expressMapper;

    @Resource
    private Gson gson;

    @Override
    @SneakyThrows
    public Map createOrder(CreateOrderDto dto) {
        System.out.println("【-------------添加订单-------------】");
        Set ign = new Setx().set("remark");
        System.out.println(dto.getShipper());
        CompleteChecker checker1 = new CompleteChecker(dto).hint("订单信息填写不完整").symbol(-401).ignore(ign);
        CompleteChecker checker2 = new CompleteChecker(dto.getShipper()).hint("寄件方信息填写不完整").last(checker1).symbol(-402);
        CompleteChecker checker3 = new CompleteChecker(dto.getRecipient()).hint("收件方信息填写不完整").last(checker2).symbol(-403);
        CompleteChecker[] checker4s = CompleteChecker.listCheckers(dto.getGlist(), "货物信息填写不完整", -404, checker3);

        Map checkResult = checker1.check();
        if (checkResult!=null){
            return checkResult;
        }
        IServiceCodeStandard service = ExpressServiceCodeEnum.EXP_RECE_CREATE_ORDER;
        Map<String, String> params = sfConfig.getParams(service);

        String oid = dto.getOid();
        String expressId = "axemallTEST" + StringUtil.getSnowId();
        CreateOrder createOrder = new CreateOrder(dto, expressId);

        MsgDataOfCreateOrder msgData = new MsgDataOfCreateOrder(createOrder.toMap());

        String msgDataReal = msgData.toJson();
        params.put("msgData", msgDataReal);
        // 签名
        params = sfConfig.sign(params);

        System.out.println("【---请求编号---】" + params.get("requestID"));
        System.out.println("【---msgData---】" + msgDataReal);
        System.out.println("【---携带数据---】" + params);

        long startTime = System.currentTimeMillis();
        String result = HttpClientUtil.post(sfConfig.apiSandbox, params);

        System.out.println("【---接口代码---】" + service.getCode());
        System.out.println("【---接口耗时---】" + (System.currentTimeMillis()-startTime));
        ;
        System.out.println("【---调用地址---】" + sfConfig.apiSandbox);
        System.out.println("【---响应结果---】" + result);
        Map<String, String> apiResult = gson.fromJson(result, Map.class);
        Map apiResultData = gson.fromJson(apiResult.get("apiResultData"),Map.class);
        String apiResultCode = apiResult.get("apiResultCode");
        if (!apiResultCode.equals("A1000")) {
            System.out.println("【---处理结果---】" + "接口调用异常");
            System.out.println("【-------------流程结束-------------】");
            return ResBuilder.bad("顺丰接口异常");
        }
        boolean is_success = apiResultData.get("success").equals(true);
        String outcome = is_success?"成功":"失败";
        System.out.println("【---处理结果---】" + outcome);
        System.out.println("【-------------流程结束-------------】");
        if (is_success){
            Map msgdata = (Map) apiResultData.get("msgData");
            List<Map> waybillNoInfoList = (List) msgdata.get("waybillNoInfoList");
            Map waybillNoInfo = waybillNoInfoList.get(0);
            String waybillNo = (String) waybillNoInfo.get("waybillNo");
            Map express = new Mapx().set("oid", dto.getOid()).set("expressId", expressId).set("waybillno",waybillNo);
            expressMapper.ins(express);
            Mapx data = new Mapx().set("waybillNo", waybillNo).set("expressId", expressId);
            return ResBuilder.ok("物流下单成功", 400, data);
        } else {
            Mapx data = new Mapx().set("reason", apiResultData.get("errorMsg"));
            return ResBuilder.fail("物流下单失败", -400, data);
        }
    }

    @Override
    @SneakyThrows
    public Map confirmOrder(UpdateOrderDto dto) {
        System.out.println("【-------------确认订单-------------】");
        CompleteChecker checker1 = new CompleteChecker(dto).hint("确认信息填写不完整").symbol(-411);

        Map checkResult = checker1.check();
        if (checkResult!=null){
            return checkResult;
        }
        IServiceCodeStandard service = ExpressServiceCodeEnum.EXP_RECE_UPDATE_ORDER;
        Map<String, String> params = sfConfig.getParams(service);

        UpdateOrder confirmOrder = new UpdateOrder(dto);

        MsgDataOfUpdateOrder msgData = new MsgDataOfUpdateOrder(confirmOrder.toMap());

        String msgDataReal = msgData.toJson();
        params.put("msgData", msgDataReal);
        // 签名
        params = sfConfig.sign(params);

        System.out.println("【---请求编号---】" + params.get("requestID"));
        System.out.println("【---msgData---】" + msgDataReal);
        System.out.println("【---携带数据---】" + params);

        long startTime = System.currentTimeMillis();
        String result = HttpClientUtil.post(sfConfig.apiSandbox, params);

        System.out.println("【---接口代码---】" + service.getCode());
        System.out.println("【---接口耗时---】" + (System.currentTimeMillis()-startTime));
        ;
        System.out.println("【---调用地址---】" + sfConfig.apiSandbox);
        System.out.println("【---响应结果---】" + result);
        Map<String, String> apiResult = gson.fromJson(result, Map.class);
        Map apiResultData = gson.fromJson(apiResult.get("apiResultData"),Map.class);
        String apiResultCode = apiResult.get("apiResultCode");
        if (!apiResultCode.equals("A1000")) {
            System.out.println("【---处理结果---】" + "接口调用异常");
            System.out.println("【-------------流程结束-------------】");
            return ResBuilder.bad("顺丰接口异常");
        }
        boolean is_success = apiResultData.get("success").equals(true);
        String outcome = is_success?"成功":"失败";
        System.out.println("【---处理结果---】" + outcome);
        System.out.println("【-------------流程结束-------------】");
        if (is_success){
            return ResBuilder.ok("确认订单成功", 401, apiResultData);
        } else {
            Mapx data = new Mapx().set("reason", apiResultData.get("errorMsg"));
            return ResBuilder.fail("确认订单失败", -410, data);
        }
    }

    @Override
    @SneakyThrows
    public Map searchOrderResp(SearchOrderResp dto) {
        System.out.println("【-------------查询订单处理结果-------------】");
        CompleteChecker checker1 = new CompleteChecker(dto).hint("查询信息填写不完整").symbol(-421);
        Map checkResult = checker1.check();
        if (checkResult!=null){
            return checkResult;
        }
        IServiceCodeStandard service = ExpressServiceCodeEnum.EXP_RECE_SEARCH_ORDER_RESP;
        Map<String, String> params = sfConfig.getParams(service);

        String msgDataReal = dto.toJson();
        params.put("msgData", msgDataReal);
        // 签名
        params = sfConfig.sign(params);

        System.out.println("【---请求编号---】" + params.get("requestID"));
        System.out.println("【---msgData---】" + msgDataReal);
        System.out.println("【---携带数据---】" + params);

        long startTime = System.currentTimeMillis();
        String result = HttpClientUtil.post(sfConfig.apiSandbox, params);

        System.out.println("【---接口代码---】" + service.getCode());
        System.out.println("【---接口耗时---】" + (System.currentTimeMillis()-startTime));
        ;
        System.out.println("【---调用地址---】" + sfConfig.apiSandbox);
        System.out.println("【---响应结果---】" + result);
        Map<String, String> apiResult = gson.fromJson(result, Map.class);
        Map apiResultData = gson.fromJson(apiResult.get("apiResultData"),Map.class);
        String apiResultCode = apiResult.get("apiResultCode");
        if (!apiResultCode.equals("A1000")) {
            System.out.println("【---处理结果---】" + "接口调用异常");
            System.out.println("【-------------流程结束-------------】");
            return ResBuilder.bad("顺丰接口异常");
        }
        boolean is_success = apiResultData.get("success").equals(true);
        String outcome = is_success?"成功":"失败";
        System.out.println("【---处理结果---】" + outcome);
        System.out.println("【-------------流程结束-------------】");
        if (is_success){
            Map msgdata = (Map) apiResultData.get("msgData");
            List<Map> waybillNoInfoList = (List) msgdata.get("waybillNoInfoList");
            Map waybillNoInfo = waybillNoInfoList.get(0);
            String waybillNo = (String) waybillNoInfo.get("waybillNo");
            Mapx data = new Mapx().set("waybillNo", waybillNo);
            return ResBuilder.ok("查询订单处理结果成功", 402, data);
        } else {
            Mapx data = new Mapx().set("reason", apiResultData.get("errorMsg"));
            return ResBuilder.fail("查询订单处理结果失败", -420, data);
        }
    }

    @Override
    @SneakyThrows
    public Map searchRoutes(String expressId) {
        System.out.println("【-------------查询路由-------------】");
        if (StringUtil.is_blank(expressId)){
            return ResBuilder.fail("未填写物流订单号", -431);
        }
        IServiceCodeStandard service = ExpressServiceCodeEnum.EXP_RECE_SEARCH_ROUTES;
        Map<String, String> params = sfConfig.getParams(service);

        SearchRoutes msgData = new SearchRoutes(expressId);

        String msgDataReal = msgData.toJson();
        params.put("msgData", msgDataReal);
        // 签名
        params = sfConfig.sign(params);

        System.out.println("【---请求编号---】" + params.get("requestID"));
        System.out.println("【---msgData---】" + msgDataReal);
        System.out.println("【---携带数据---】" + params);

        long startTime = System.currentTimeMillis();
        String result = HttpClientUtil.post(sfConfig.apiSandbox, params);

        System.out.println("【---接口代码---】" + service.getCode());
        System.out.println("【---接口耗时---】" + (System.currentTimeMillis()-startTime));
        ;
        System.out.println("【---调用地址---】" + sfConfig.apiSandbox);
        System.out.println("【---响应结果---】" + result);
        Map<String, String> apiResult = gson.fromJson(result, Map.class);
        Map apiResultData = gson.fromJson(apiResult.get("apiResultData"),Map.class);
        String apiResultCode = apiResult.get("apiResultCode");
        if (!apiResultCode.equals("A1000")) {
            System.out.println("【---处理结果---】" + "接口调用异常");
            System.out.println("【-------------流程结束-------------】");
            return ResBuilder.bad("顺丰接口异常");
        }
        boolean is_success = apiResultData.get("success").equals(true);
        String outcome = is_success?"成功":"失败";
        System.out.println("【---处理结果---】" + outcome);
        System.out.println("【-------------流程结束-------------】");
        if (is_success){
            return ResBuilder.ok("查询路由成功", 403, apiResultData);
        } else {
            Mapx data = new Mapx().set("reason", apiResultData.get("errorMsg"));
            return ResBuilder.fail("查询路由失败", -430, data);
        }
    }

    @Override
    @SneakyThrows
    public Map searchPromitm(String waybillNo) {
        System.out.println("【-------------查询预计时间-------------】");
        if (StringUtil.is_blank(waybillNo)){
            return ResBuilder.fail("未填写运单号", -441);
        }
        IServiceCodeStandard service = ExpressServiceCodeEnum.EXP_RECE_SEARCH_PROMITM;
        Map<String, String> params = sfConfig.getParams(service);

        SearchPromitm msgData = new SearchPromitm(waybillNo);

        String msgDataReal = msgData.toJson();
        params.put("msgData", msgDataReal);
        // 签名
        params = sfConfig.sign(params);

        System.out.println("【---请求编号---】" + params.get("requestID"));
        System.out.println("【---msgData---】" + msgDataReal);
        System.out.println("【---携带数据---】" + params);

        long startTime = System.currentTimeMillis();
        String result = HttpClientUtil.post(sfConfig.apiSandbox, params);

        System.out.println("【---接口代码---】" + service.getCode());
        System.out.println("【---接口耗时---】" + (System.currentTimeMillis()-startTime));
        ;
        System.out.println("【---调用地址---】" + sfConfig.apiSandbox);
        System.out.println("【---响应结果---】" + result);
        Map<String, String> apiResult = gson.fromJson(result, Map.class);
        Map apiResultData = gson.fromJson(apiResult.get("apiResultData"),Map.class);
        String apiResultCode = apiResult.get("apiResultCode");
        if (!apiResultCode.equals("A1000")) {
            System.out.println("【---处理结果---】" + "接口调用异常");
            System.out.println("【-------------流程结束-------------】");
            return ResBuilder.bad("顺丰接口异常");
        }
        boolean is_success = apiResultData.get("success").equals(true);
        String outcome = is_success?"成功":"失败";
        System.out.println("【---处理结果---】" + outcome);
        System.out.println("【-------------流程结束-------------】");
        if (is_success){
            Object x = apiResultData.get("msgData");
            return ResBuilder.ok("查询预计时间成功", 404, x);
        } else {
            Mapx data = new Mapx().set("reason", apiResultData.get("errorMsg"));
            return ResBuilder.fail("查询预计时间失败", -440, data);
        }
    }

}
